module vct_dda_4441 (Z, X, Y);
	
	input [3:0] Y;
	input [3:0] X;
	output [3:0] Z;
	
	wire [4:0] S;
	wire [4:0] C;
	wire [3:0] carry;
	
	// generate the partial products.
	wire N0_0_3;
	and pp1(N0_0_3, X[3], Y[0]);
	wire N0_1_3;
	and pp2(N0_1_3, X[2], Y[1]);
	wire N0_1_4;
	and pp3(N0_1_4, X[3], Y[1]);
	wire N0_2_3;
	and pp4(N0_2_3, X[1], Y[2]);
	wire N0_2_4;
	and pp5(N0_2_4, X[2], Y[2]);
	wire N0_2_5;
	and pp6(N0_2_5, X[3], Y[2]);
	wire N0_3_3;
	and pp7(N0_3_3, X[0], Y[3]);
	wire N0_3_4;
	and pp8(N0_3_4, X[1], Y[3]);
	wire N0_3_5;
	and pp9(N0_3_5, X[2], Y[3]);
	wire N0_3_6;
	and pp10(N0_3_6, X[3], Y[3]);
	wire N0_4_3;
	and pp11(N0_4_3, X[1], Y[1]);
	wire N0_5_3;
	and pp12(N0_5_3, X[0], Y[2]);

	// PP Reduction
	// Elements from matrix 0 
	// Elements from matrix 1 
	// In matrix 1 adding FA to column 3 
	wire N2_0_3;
	wire N2_1_4;
	full_adder FA1(N2_1_4, N2_0_3, N0_0_3, N0_1_3, N0_2_3);
	// Elements from matrix 2 
	// In matrix 2 adding HA to column 3 
	wire N3_0_3;
	wire N3_1_4;
	half_adder HA1(N3_1_4, N3_0_3, N0_3_3, N0_4_3);
	// In matrix 2 adding FA to column 4 
	wire N3_0_4;
	wire N3_1_5;
	full_adder FA2(N3_1_5, N3_0_4, N0_1_4, N0_2_4, N0_3_4);
	// Elements from matrix 3 
	// In matrix 3 adding HA to column 3 
	wire N4_0_3;
	wire N4_1_4;
	half_adder HA2(N4_1_4, N4_0_3, N0_5_3, N2_0_3);
	// In matrix 3 adding FA to column 4 
	wire N4_0_4;
	wire N4_1_5;
	full_adder FA3(N4_1_5, N4_0_4, N2_1_4, N3_0_4, N3_1_4);
	// In matrix 3 adding FA to column 5 
	wire N4_0_5;
	wire N4_1_6;
	full_adder FA4(N4_1_6, N4_0_5, N0_2_5, N0_3_5, N3_1_5);

	buf bufC0(C[0], N3_0_3);
	buf bufC1(C[1], N4_0_4);
	buf bufC2(C[2], N4_0_5);
	buf bufC3(C[3], N0_3_6);
	buf bufS0(S[0], N4_0_3);
	buf bufS1(S[1], N4_1_4);
	buf bufS2(S[2], N4_1_5);
	buf bufS3(S[3], N4_1_6);

	and CPA1(carry[0],C[0],S[0]);
	full_adder CPA2(carry[1],Z[0],carry[0],C[1],S[1]);
	full_adder CPA3(carry[2],Z[1],carry[1],C[2],S[2]);
	full_adder CPA4(Z[3],Z[2],carry[2],C[3],S[3]);
endmodule
